/*
 * @Author: lei
 * @Description:  C++11实践之future
 * @FilePath: /code/async.cc
 */

#include <future>
#include <iostream>
//父线程 向 子线程 要数据
int Add1(int target)
{
    int sum=0;
    for(int i=0;i<target;i++)
        sum+=i;
    return sum;
}
void test1()
{
    int n;
    std::cin>>n;
    std::future<int> ans_future=std::async(std::launch::async,Add1,n);
    //do something else
    int ans=ans_future.get();//一个future对象只能get一次，除非使用shared_future
    std::cout<<ans<<std::endl;
}


//父线程 向 子线程 传数据
//父线程 向 子线程 要数据
int Add2(std::future<int>& tar)
{
    int sum=0;
    int target=tar.get();
    for(int i=0;i<target;i++)
        sum+=i;
    return sum;
}
void test2()
{
    std::promise<int> p;
    std::future<int> f=p.get_future();
    std::future<int> ans_future=std::async(std::launch::async,Add2,std::ref(f));

    int n;
    std::cin>>n;
    p.set_value(n);

    int ans=ans_future.get();
    std::cout<<ans<<std::endl;
}

//多个异步任务，shared_future使用
int Add3(std::shared_future<int>& tar)
{
    int sum=0;
    int target=tar.get();
    for(int i=0;i<target;i++)
        sum+=i;
    return sum;
}
void test3()
{
    std::promise<int> p;
    std::future<int> f=p.get_future();
    std::shared_future<int> sf=f.share();//so great, 如果n次任务，就不需要n个future和n个promise了

    std::future<int> ans_future1=std::async(std::launch::async,Add3,std::ref(sf));
    std::future<int> ans_future2=std::async(std::launch::async,Add3,std::ref(sf));
    std::future<int> ans_future3=std::async(std::launch::async,Add3,std::ref(sf));

    int n;
    std::cin>>n;
    p.set_value(n);

    std::cout<<ans_future1.get()<<std::endl;
    std::cout<<ans_future2.get()<<std::endl;
    std::cout<<ans_future3.get()<<std::endl;
}


int main()
{
    //test1();
    //test2();
    test3();
    return 0;
}
//promise 只能被移动，而future可以被复制
//std::future和std::promise都是模板类，而其模板参数是 要传输的值的类型 ；本文件中为int